﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeresyManager.Comunication;

namespace HeresyManager.Careers
{
    [Serializable]
    public class Assassin : Career
    {

        private Skill[] skills;
        private Talent[] talents;

        public Assassin()
        {
        }

        public override Rank[] Ranks
        {
            get { return new Rank[] { new SellSteel(), new Shadesman(), new Nighthawk(), new Secluse(), new Assasin(), new DeathAdept(), new Freeblade(), new Nihilator(), new ImperatorMortis(), new AssassinAtMarque(), new AssassinPlatine() }; }
        }

        public override BackgroundPackage[] BackgroundPackages
        {
            get { return new BackgroundPackage[] { new TheAstralKnives(), new TheMoritat(), new TheSonsOfDispater() }; }
        }

        public override IEnumerator<Comunicator> Acire(Character c)
        {
            skills = new Skill[] { new Skills.SpeakLanguages.SpeakLanguageLowGothic(Skill.SkillLevel.Skilled), new Skills.Awareness(Skill.SkillLevel.Skilled), new Skills.Dodge(Skill.SkillLevel.Skilled) };
            foreach (var s in skills)
            {
                var en = c.AddSkill(s, this);
                while (en.MoveNext())
                    yield return en.Current;
            }
            List<Talent> list = new List<Talent>();
            Talent t = new Talents.WeaponTraining.MeleeWeaponTrainingPrimitive();
            c.AddTalent(t, this);
            list.Add(t);
            t = null;
            while (t == null)
            {
                var choose = new ChooseOne<Talent>("Choose One", new Talents.Unremarkable(), new Talents.Ambidextrous());
                while (choose.SelectedValue == null)
                    yield return choose;
                t = choose.SelectedValue;
            }
            c.AddTalent(t, this);
            list.Add(t);
            t = null;
            while (t == null)
            {
                var choose = new ChooseOne<Talent>("Choose One", new Talents.WeaponTraining.ThrownWeaponTrainingPrimitive(), new Talents.WeaponTraining.PistolTrainingLas());
                yield return choose;
                t = choose.SelectedValue;
            }
            c.AddTalent(t, this);
            list.Add(t);
            t = new Talents.WeaponTraining.BasicWeaponTrainingSP();
            c.AddTalent(t, this);
            list.Add(t);
            t = new Talents.WeaponTraining.PistolTrainingSP();
            c.AddTalent(t, this);
            list.Add(t);
            talents = list.ToArray();

        }

        public override void DeAcire(Character c)
        {
            foreach (var s in skills)
            {
                c.RemoveSkill(s, this);
            }

            foreach (var item in talents)
            {
                c.RemoveTalent(item, this);
            }
            this.talents = null;
        }

        public override string Name
        {
            get { return "Assasin"; }
        }

        #region Ranks

        [Serializable]
        private class SellSteel : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Climb(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Drives.DriveGroundVehicle(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Inquiry(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Pilots.PilotCivilianCraft(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.SilentMove(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Swim(Skill.SkillLevel.Skilled)),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingLas()),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingPrimitive()),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingSP()),
                new TalentBuyable(new Talents.Catfall()),
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesSight()),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingLas()),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingPrimitive()),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingSP()),
                new TalentBuyable(new Talents.SoundConstitution()),
                new TalentBuyable(new Talents.SoundConstitution()),
                new TalentBuyable(new Talents.WeaponTraining.ThrownWeaponTrainingPrimitive()),
                new SkillBuyable(new Skills.Literacy(Skill.SkillLevel.Skilled),200)
            };


            public override int MinimumExp
            {
                get { return 0; }
            }

            public override string Name
            {
                get { return "Sell-Steel"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }


        }

        [Serializable]
        private class Shadesman : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Acrobatics(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Cipherses.CiphersAcolyte(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreUnderworld(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Drives.DriveGroundVehicle(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Drives.DriveHover(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Navigations.NavigationSurface(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Pilots.PilotCivilianCraft(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Security(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Shadowing(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Swim(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Tracking(Skill.SkillLevel.Skilled)),
               
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesHearing()),
                new TalentBuyable(new Talents.BerserkCharge()),
                new TalentBuyable(new Talents.FuriousAssault()),
                new TalentBuyable(new Talents.SoundConstitution()),
                new SkillBuyable(new Skills.SpeakLanguages.SpeakLanguageLowGothic(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Wrangling(Skill.SkillLevel.Skilled)),
                new TalentBuyable(new Talents.Sprint()),
                new TalentBuyable(new Talents.SureStrike()),
            };


            public override int MinimumExp
            {
                get { return 500; }
            }

            public override string Name
            {
                get { return "Shadesman"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is SellSteel);
            }
        }

        [Serializable]
        private class Nighthawk : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.ChemUse(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Cipherses.CiphersWarCant(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Climb(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreImperialCreed(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreUnderworld(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreWar(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Concealment(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Dodge(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Drives.DriveGroundVehicle(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Pilots.PilotCivilianCraft(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.SecretTongues.SecretTongueAcolyte(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.SilentMove(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Swim(Skill.SkillLevel.Master)),
               
                new TalentBuyable(new Talents.CrackShot()),
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesSmell()),
                new TalentBuyable(new Talents.Jaded()),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingFlame()),
                new TalentBuyable(new Talents.RapidReload()),
                new SkillBuyable(new Skills.SlightOfHand(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Survival(Skill.SkillLevel.Skilled),200),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingFlame(),200),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingLauncher(),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingSP(),200),
                new TalentBuyable(new Talents.WeaponTraining.MeleeWeaponTrainingShock(),200),
                new TalentBuyable(new Talents.MightyShot(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.SwiftAttack(),200),
                new TalentBuyable(new Talents.TwoWeaponWielders.TwoWeaponWielderBalistic(),200),
                new TalentBuyable(new Talents.TwoWeaponWielders.TwoWeaponWielderMelee(),200),
            };


            public override int MinimumExp
            {
                get { return 1000; }
            }

            public override string Name
            {
                get { return "Nighthawk"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Shadesman);
            }

        }

        [Serializable]
        private class Secluse : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Acrobatics(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Awareness(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ChemUse(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Cipherses.CiphersWarCant(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreUnderworld(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Drives.DriveHover(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Inquiry(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreImperialCreed(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Scrutiny(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Search(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Security(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Tracking(Skill.SkillLevel.Advanced)),

               
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingBolt()),
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesTast()),
                new TalentBuyable(new Talents.LightningReflexes()),
                new TalentBuyable(new Talents.WeaponTraining.MeleeWeaponTrainingChain()),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingBolt()),
                new TalentBuyable(new Talents.QuickDraw()),
                new SkillBuyable(new Skills.CommonLores.CommonLoreEcclesiarchy(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.LipReading(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.SpeakLanguages.SpeakLanguageHighGothic(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.TechUse(Skill.SkillLevel.Skilled),200),
                new TalentBuyable(new Talents.DeadeyeShot(),200),
                new TalentBuyable(new Talents.DualShot(),200),
                new TalentBuyable(new Talents.ExoticWeaponTraining("Needle Pistol"),200),
                new TalentBuyable(new Talents.ExoticWeaponTraining("Web Pistol"),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingFlame(),200),
                new TalentBuyable(new Talents.HipShooting(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.WeaponTraining.ThrownWeaponTrainingShock(),200)
            };


            public override int MinimumExp
            {
                get { return 2000; }
            }

            public override string Name
            {
                get { return "Secluse"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Nighthawk);
            }

        }


        [Serializable]
        private class Assasin : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Contortionist(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Disguise(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Dodge(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Inquiry(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Interrogation(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Intimidate(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Search(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Cipherses.CiphersAcolyte(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Security(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Shadowing(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Tracking(Skill.SkillLevel.Master)),

               
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesTouch()),
                new TalentBuyable(new Talents.LeapUp()),
                new TalentBuyable(new Talents.WeaponTraining.MeleeWeaponTrainingPower()),
                new TalentBuyable(new Talents.RapidReaction()),

                new SkillBuyable(new Skills.ChemUse(Skill.SkillLevel.Master),200),
                new SkillBuyable(new Skills.Cipherses.CiphersUnderworld(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Medicae(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreChymistry(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreHeraldry(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.TechUse(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.Wrangling(Skill.SkillLevel.Advanced),200),

                new TalentBuyable(new Talents.LightningAttack(),200),
                new TalentBuyable(new Talents.Marksman(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.WeaponTraining.ThrownWeaponTrainingChain(),200),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingPlasma(),200),
                new TalentBuyable(new Talents.Blademaster(),200),
                new TalentBuyable(new Talents.ExoticWeaponTraining("Needle Rifle"),200),
                new TalentBuyable(new Talents.ExoticWeaponTraining("Webber"),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingLauncher(),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingPrimitive(),200),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingPlasma(),200),
                new TalentBuyable(new Talents.Sharpshooter(),200)
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Secluse);
            }
            public override int MinimumExp
            {
                get { return 3000; }
            }

            public override string Name
            {
                get { return "Assassin"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }


        }

        [Serializable]
        private class DeathAdept : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Cipherses.CiphersWarCant(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Climb(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Concealment(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Contortionist(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Drives.DriveWalker(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Intimidate(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.SilentMove(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Survival(Skill.SkillLevel.Advanced)),

               
                new TalentBuyable(new Talents.Ambidextrous()),
                new TalentBuyable(new Talents.AssyssinStrike()),
                new TalentBuyable(new Talents.DoubleTeam()),

                new TalentBuyable(new Talents.BlindFighting(),200),
                new TalentBuyable(new Talents.CounterAttack(),200),
                new TalentBuyable(new Talents.DualStrike(),200),
                new TalentBuyable(new Talents.Frenzy(),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingBolt(),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingLas(),200),
                new TalentBuyable(new Talents.NervesOfSteel(),200),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingMelta(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.StepASide(),200),
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && !c.Ranks.Any(t => t is Freeblade) && c.Ranks.Any(t => t is Assasin);
            }

            public override int MinimumExp
            {
                get { return 6000; }
            }

            public override string Name
            {
                get { return "Death Adept"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }


        }


        [Serializable]
        private class Freeblade : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Disguise(Skill.SkillLevel.Advanced)),

               
                new TalentBuyable(new Talents.LightSleeper()),
                new TalentBuyable(new Talents.Resistances.ResistancePoisons()),
                new TalentBuyable(new Talents.Unremarkable()),

                new SkillBuyable(new Skills.Blather(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Charm(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Deceive(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Demolition(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Scrutiny(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.SecretTongues.SecretTongueAcolyte(Skill.SkillLevel.Advanced),200),


                new TalentBuyable(new Talents.Talented(new Skills.Charm(Skill.SkillLevel.Advanced)),200),
                new TalentBuyable(new Talents.Talented(new Skills.Inquiry(Skill.SkillLevel.Advanced)),200),
                new TalentBuyable(new Talents.Talented(new Skills.Shadowing(Skill.SkillLevel.Advanced)),200),
                
                new SkillBuyable(new Skills.Gamble(Skill.SkillLevel.Skilled),300),
                new SkillBuyable(new Skills.Cipherses.CiphersSecretSociety(Skill.SkillLevel.Skilled),300),
                
                new TalentBuyable(new Talents.Peers.PeerUnderworld(),300),
                new TalentBuyable(new Talents.SoundConstitution(),300)
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && !c.Ranks.Any(t => t is DeathAdept) && c.Ranks.Any(t => t is Assasin);
            }

            public override int MinimumExp
            {
                get { return 6000; }
            }

            public override string Name
            {
                get { return "Freeblade"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }


        }


        [Serializable]
        private class Nihilator : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Awareness(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Contortionist(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Shadowing(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Survival(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Pilots.PilotMilitaryCraft(Skill.SkillLevel.Master)),

               
                new TalentBuyable(new Talents.Disarm()),


                new TalentBuyable(new Talents.CombatMaster(),200),
                new TalentBuyable(new Talents.CripplingStrike(),200),
                new TalentBuyable(new Talents.HardTarget(),200),
                new TalentBuyable(new Talents.PreciseBlow(),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingMelta(),200),
                new TalentBuyable(new Talents.WeaponTraining.HeavyWeaponTrainingPlasma(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.WeaponTraining.ThrownWeaponTrainingPower(),200)                
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is DeathAdept);
            }

            public override int MinimumExp
            {
                get { return 8000; }
            }

            public override string Name
            {
                get { return "Nihilator"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }


        }

        [Serializable]
        private class ImperatorMortis : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Acrobatics(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Concealment(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Intimidate(Skill.SkillLevel.Master)),
                
                new SkillBuyable(new Skills.Pilots.PilotMilitaryCraft(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.SlightOfHand(Skill.SkillLevel.Advanced),200),

                new TalentBuyable(new Talents.BattleRage(),200),
                new TalentBuyable(new Talents.DeflectShot(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.WallOfSteel(),200),
                new TalentBuyable(new Talents.ArmsMaster(),200),
                new TalentBuyable(new Talents.Fearless(),200),
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Nihilator);
            }

            public override int MinimumExp
            {
                get { return 10000; }
            }

            public override string Name
            {
                get { return "Imperator Mortis"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class AssassinAtMarque : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Search(Skill.SkillLevel.Master)),
                
                new TalentBuyable(new Talents.Resistances.ResistanceFear()),

                new SkillBuyable(new Skills.Charm(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.Deceive(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.Demolition(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.Interrogation(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.LipReading(Skill.SkillLevel.Advanced),200),

                new TalentBuyable(new Talents.Gunslinger(),200),
                new TalentBuyable(new Talents.IndependentTargeting(),200),
                new TalentBuyable(new Talents.Talented(new Skills.ChemUse(Skill.SkillLevel.Basic)),200),
                new TalentBuyable(new Talents.Talented(new Skills.Deceive(Skill.SkillLevel.Basic)),200),
                new TalentBuyable(new Talents.Talented(new Skills.Interrogation(Skill.SkillLevel.Basic)),200),

                new SkillBuyable(new Skills.Command(Skill.SkillLevel.Skilled),300),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreLegend(Skill.SkillLevel.Skilled),300),
            
                new TalentBuyable(new Talents.SoundConstitution(),300)
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Freeblade);
            }

            public override int MinimumExp
            {
                get { return 8000; }
            }

            public override string Name
            {
                get { return "Assassin At Marque"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }

        }

        [Serializable]
        private class AssassinPlatine : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Disguise(Skill.SkillLevel.Master)),
                
                new SkillBuyable(new Skills.Blather(Skill.SkillLevel.Master),200),
                new SkillBuyable(new Skills.Carouse(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Deceive(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.SpeakLanguages.SpeakLanguageHighGothic(Skill.SkillLevel.Advanced),200),

                new TalentBuyable(new Talents.Talented(new Skills.Blather(Skill.SkillLevel.Basic)),200),
                new TalentBuyable(new Talents.Talented(new Skills.Disguise(Skill.SkillLevel.Basic)),200),
                new TalentBuyable(new Talents.Talented(new Skills.Scrutiny(Skill.SkillLevel.Basic)),200),

                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreCults(Skill.SkillLevel.Skilled),300),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLorePsykers(Skill.SkillLevel.Skilled),300),
                new SkillBuyable(new Skills.Logic(Skill.SkillLevel.Skilled),300),
            
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingMelta(),300),
                new TalentBuyable(new Talents.Resistances.ResistancePsychicPowers(),300),
                new TalentBuyable(new Talents.SoundConstitution(),300)
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is AssassinAtMarque);
            }

            public override int MinimumExp
            {
                get { return 10000; }
            }

            public override string Name
            {
                get { return "Assassin Platine"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }

        }



        #endregion

        #region BackroundPackage

        [Serializable]
        private class TheAstralKnives : BackgroundPackage
        {

            private Skill[] skills;

            private int coruption;

            public override string Name
            {
                get { return "The Astral Knives"; }
            }

            public override int Cost
            {
                get { return 200; }
            }

            public override bool IsPreconditionSattisfied(Character c)
            {
                return base.IsPreconditionSattisfied(c) && c.HomeWorld is HomeWorlds.VoidBorn;
            }

            public override IEnumerator<Comunicator> Accire(Character c)
            {
                var en = base.Accire(c);
                while (en.MoveNext())
                    yield return en.Current;

                skills = new Skill[] { new Skills.Cipherses.CiphersSecretSociety(Skill.SkillLevel.Skilled, "Astral Knives"), new Skills.Deceive(Skill.SkillLevel.Skilled), new Skills.ForbiddenLores.ForbiddenLoreWarp(Skill.SkillLevel.Basic), new Skills.TechUse(Skill.SkillLevel.Basic) };
                foreach (var s in skills)
                {
                    en = c.AddSkill(s, this);
                    while (en.MoveNext())
                        yield return en.Current;
                }

                var rolDie = new RoleDice("Coruption", Dice.D5);
                while (rolDie.Value == -1)
                    yield return rolDie;
                coruption = rolDie.Value;
                c.CorruptionPoints += coruption;
            }

            public override void DeAccire(Character c)
            {
                base.DeAccire(c);
                foreach (var s in skills)
                {
                    c.RemoveSkill(s, this);
                }

                c.CorruptionPoints -= coruption;

            }
        }

        [Serializable]
        private class TheSonsOfDispater : BackgroundPackage
        {

            private Skill[] skills;

            public override string Name
            {
                get { return "The Sons of Dispater"; }
            }

            public override int Cost
            {
                get { return 100; }
            }



            public override IEnumerator<Comunicator> Accire(Character c)
            {
                var en = base.Accire(c);
                while (en.MoveNext())
                    yield return en.Current;

                skills = new Skill[] { new Skills.CommonLores.CommonLoreUnderworld(Skill.SkillLevel.Skilled), new Skills.Intimidate(Skill.SkillLevel.Skilled), new Skills.Security(Skill.SkillLevel.Skilled) };
                foreach (var s in skills)
                {
                    en = c.AddSkill(s, this);
                    while (en.MoveNext())
                        yield return en.Current;
                }

                //TODO Replace Equipment


            }

            public override void DeAccire(Character c)
            {
                base.DeAccire(c);
                foreach (var s in skills)
                {
                    c.RemoveSkill(s, this);
                }



            }
        }

        [Serializable]
        private class TheMoritat : BackgroundPackage
        {

            private Skill[] skills;

            private Talent talent;

            private Trait trait;

            private int insanety;

            public override string Name
            {
                get { return "The Moritat"; }
            }

            public override int Cost
            {
                get { return 300; }
            }

            public override bool IsPreconditionSattisfied(Character c)
            {
                return base.IsPreconditionSattisfied(c) && c.HomeWorld is HomeWorlds.FeralWorld || c.HomeWorld is HomeWorlds.ImperialWorld || c.HomeWorld is HomeWorlds.HiveWorld;
            }

            public override IEnumerator<Comunicator> Accire(Character c)
            {
                var en = base.Accire(c);
                while (en.MoveNext())
                    yield return en.Current;

                c.Fel -= 5;

                talent = new Talents.Jaded();
                trait = new Traits.TheBloodyEdge();

                c.AddTrait(trait, this);
                en = c.AddTalent(talent, this);
                while (en.MoveNext())
                    yield return en.Current;

                skills = new Skill[] { new Skills.SecretTongues.SecretTongueOther(Skill.SkillLevel.Skilled, "Moritat"), new Skills.Shadowing(Skill.SkillLevel.Skilled), new Skills.SilentMove(Skill.SkillLevel.Skilled) };
                foreach (var s in skills)
                {
                    en = c.AddSkill(s, this);
                    while (en.MoveNext())
                        yield return en.Current;
                }

                //TODO Replace Gear

                var rolDie = new RoleDice("Insanaty", Dice.D5);
                while (rolDie.Value == -1)
                    yield return rolDie;
                insanety = rolDie.Value;

                c.InsanityPoints += insanety;
            }

            public override void DeAccire(Character c)
            {
                base.DeAccire(c);
                c.RemoveTalent(talent, this);
                c.RemoveTrait(trait, this);
                foreach (var s in skills)
                {
                    c.RemoveSkill(s, this);
                }
                c.Fel += 5;

                c.InsanityPoints -= insanety;

            }
        }

        #endregion




        public override int[] WeaponSkillCost
        {
            get { return new int[] { 100, 250, 500, 750 }; }
        }

        public override int[] BalisticSkillCost
        {
            get { return new int[] { 100, 250, 500, 750 }; }
        }

        public override int[] StrengthCost
        {
            get { return new int[] { 500, 750, 1000, 2500 }; }
        }

        public override int[] ToughnessCost
        {
            get { return new int[] { 250, 500, 750, 1000 }; ; }
        }

        public override int[] AgilityCost
        {
            get { return new int[] { 100, 250, 500, 500 }; }
        }

        public override int[] IntelligenceCost
        {
            get { return new int[] { 250, 500, 750, 1000 }; }
        }

        public override int[] PerceptionCost
        {
            get { return new int[] { 250, 500, 750, 1000 }; }
        }

        public override int[] WillpowerCost
        {
            get { return new int[] { 250, 500, 750, 1000 }; }
        }

        public override int[] FellowshipCost
        {
            get { return new int[] { 500, 750, 1000, 2500 }; }
        }
    }
}
